home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / wwbbs31_source.lha / WWBBS / Library / users_lib.c < prev    next >
C/C++ Source or Header  |  1995-06-23  |  43KB  |  1,271 lines

  1. #include "wwbbs.h"
  2. #include "users.h"
  3.  
  4. void checkpoint(BYTE *);
  5.  
  6. struct Node *GetUserNode(BYTE *name,LONG accessmode)
  7.     {
  8.         struct Node *ret=NULL;
  9.         if(name && strlen(name))
  10.             {
  11.                 ObtainSemaphoreShared(&UserSemaphore);
  12.                 {
  13.                     struct Node *node=NULL;
  14.                     if(node=FindUser(name))
  15.                         {
  16.                             switch(accessmode)
  17.                                 {
  18.                                     case EXCLUSIVE_LOCK:
  19.                                         ObtainSemaphore(&(((struct UserNode *) node)->un_Semaphore));
  20.                                         break;
  21.                                     case SHARED_LOCK:
  22.                                     default:
  23.                                         ObtainSemaphoreShared(&(((struct UserNode *) node)->un_Semaphore));
  24.                                         break;
  25.                                 }
  26.                             ret=node;
  27.                         }
  28.                     else
  29.                         ReleaseSemaphore(&UserSemaphore);
  30.                 }
  31.             }
  32.         return(ret);
  33.     }
  34.  
  35. void FreeUserNode(struct Node *node)
  36.     {
  37.         ReleaseSemaphore(&(((struct UserNode *) node)->un_Semaphore));
  38.         ReleaseSemaphore(&UserSemaphore);
  39.     }
  40.  
  41. ULONG GetUserInfoFields(struct Node *node,struct TagItem *tags_orig)
  42.     {
  43.         ULONG ret=0;
  44.         struct TagItem *tags;
  45.         if(tags=CloneTagItems(tags_orig))
  46.             {
  47.                 if(FilterTagItems(tags,usrinfo_tags,TAGFILTER_AND))
  48.                     {
  49.                         struct UserInfo *ui=NULL;
  50.                         struct TagItem *tstate,*tag;
  51.                         APTR data;
  52.                         {
  53.                             if(tag=FindTagItem(UNTAG_UserInfo,((struct UserNode *) node)->un_Pointers))
  54.                                 {
  55.                                     if(tag->ti_Data)
  56.                                         ui=(struct UserInfo *) tag->ti_Data;
  57.                                 }
  58.                         }
  59.                         if(ui)
  60.                             {
  61.                                 tstate=tags;
  62.                                 while(tag=NextTagItem(&tstate))
  63.                                     {
  64.                                         data=(APTR) tag->ti_Data;
  65.                                         switch(tag->ti_Tag)
  66.                                             {
  67.                                                 case USRTAG_Password:
  68.                                                     strcpy((STRPTR) data,ui->ui_Password);
  69.                                                     break;
  70.                                                 case USRTAG_Address:
  71.                                                     strcpy((STRPTR) data,ui->ui_Address);
  72.                                                     break;
  73.                                                 case USRTAG_City:
  74.                                                     strcpy((STRPTR) data,ui->ui_City);
  75.                                                     break;
  76.                                                 case USRTAG_State:
  77.                                                     strcpy((STRPTR) data,ui->ui_State);
  78.                                                     break;
  79.                                                 case USRTAG_Zip:
  80.                                                     strcpy((STRPTR) data,ui->ui_Zip);
  81.                                                     break;
  82.                                                 case USRTAG_Country:
  83.                                                     strcpy((STRPTR) data,ui->ui_Country);
  84.                                                     break;
  85.                                                 case USRTAG_PhoneCode:
  86.                                                     strcpy((STRPTR) data,ui->ui_PhoneCode);
  87.                                                     break;
  88.                                                 case USRTAG_PhoneNumber:
  89.                                                     strcpy((STRPTR) data,ui->ui_PhoneNumber);
  90.                                                     break;
  91.                                                 case USRTAG_BirthDay:
  92.                                                     *((UBYTE *) data)=ui->ui_BirthDay;
  93.                                                     break;
  94.                                                 case USRTAG_BirthMonth:
  95.                                                     *((UBYTE *) data)=ui->ui_BirthMonth;
  96.                                                     break;
  97.                                                 case USRTAG_BirthYear:
  98.                                                     *((UWORD *) data)=ui->ui_BirthYear;
  99.                                                     break;
  100.                                             }
  101.                                         ret++;
  102.                                     }
  103.                             }
  104.                     }
  105.                 FreeTagItems(tags);
  106.             }
  107.         return(ret);
  108.     }
  109.  
  110. ULONG SetUserInfoFields(struct Node *node,struct TagItem *tags_orig)
  111.     {
  112.         ULONG ret=0,retminus=0;
  113.         struct TagItem *tags;
  114.         if(tags=CloneTagItems(tags_orig))
  115.             {
  116.                 if(FilterTagItems(tags,usrinfo_tags,TAGFILTER_AND))
  117.                     {
  118.                         struct UserInfo *ui=NULL;
  119.                         struct TagItem *tstate,*tag;
  120.                         APTR data;
  121.                         {
  122.                             if(tag=FindTagItem(UNTAG_UserInfo,((struct UserNode *) node)->un_Pointers))
  123.                                 {
  124.                                     if(tag->ti_Data)
  125.                                         ui=(struct UserInfo *) tag->ti_Data;
  126.                                 }
  127.                         }
  128.                         if(ui)
  129.                             {
  130.                                 tstate=tags;
  131.                                 while(tag=NextTagItem(&tstate))
  132.                                     {
  133.                                         data=(APTR) tag->ti_Data;
  134.                                         switch(tag->ti_Tag)
  135.                                             {
  136.                                                 case USRTAG_Password:
  137.                                                     if(data && strlen((STRPTR) data)<=10)
  138.                                                         strcpy(ui->ui_Password,(STRPTR) data);
  139.                                                     else
  140.                                                         retminus++;
  141.                                                     break;
  142.                                                 case USRTAG_Address:
  143.                                                     if(data && strlen((STRPTR) data)<=30)
  144.                                                         strcpy(ui->ui_Address,(STRPTR) data);
  145.                                                     else
  146.                                                         retminus++;
  147.                                                     break;
  148.                                                 case USRTAG_City:
  149.                                                     if(data && strlen((STRPTR) data)<=20)
  150.                                                         strcpy(ui->ui_City,(STRPTR) data);
  151.                                                     else
  152.                                                         retminus++;
  153.                                                     break;
  154.                                                 case USRTAG_State:
  155.                                                     if(data && strlen((STRPTR) data)<=20)
  156.                                                         strcpy(ui->ui_State,(STRPTR) data);
  157.                                                     else
  158.                                                         retminus++;
  159.                                                     break;
  160.                                                 case USRTAG_Zip:
  161.                                                     if(data && strlen((STRPTR) data)<=10)
  162.                                                         strcpy(ui->ui_Zip,(STRPTR) data);
  163.                                                     else
  164.                                                         retminus++;
  165.                                                     break;
  166.                                                 case USRTAG_Country:
  167.                                                     if(data && strlen((STRPTR) data)<=3)
  168.                                                         strcpy(ui->ui_Country,(STRPTR) data);
  169.                                                     else
  170.                                                         retminus++;
  171.                                                     break;
  172.                                                 case USRTAG_PhoneCode:
  173.                                                     if(data && strlen((STRPTR) data)<=6)
  174.                                                         strcpy(ui->ui_PhoneCode,(STRPTR) data);
  175.                                                     else
  176.                                                         retminus++;
  177.                                                     break;
  178.                                                 case USRTAG_PhoneNumber:
  179.                                                     if(data && strlen((STRPTR) data)<=8)
  180.                                                         strcpy(ui->ui_PhoneNumber,(STRPTR) data);
  181.                                                     else
  182.                                                         retminus++;
  183.                                                     break;
  184.                                                 case USRTAG_BirthDay:
  185.                                                     ui->ui_BirthDay=(UBYTE) data;
  186.                                                     break;
  187.                                                 case USRTAG_BirthMonth:
  188.                                                     ui->ui_BirthMonth=(UBYTE) data;
  189.                                                     break;
  190.                                                 case USRTAG_BirthYear:
  191.                                                     ui->ui_BirthYear=(UWORD) data;
  192.                                                     break;
  193.                                             }
  194.                                         ret++;
  195.                                     }
  196.                             }
  197.                     }
  198.                 FreeTagItems(tags);
  199.             }
  200.         ret-=retminus;
  201.         return(ret);
  202.     }
  203.  
  204. ULONG GetUserAccessFields(struct Node *node,struct TagItem *tags_orig)
  205.     {
  206.         ULONG ret=0;
  207.         struct TagItem *tags;
  208.         if(tags=CloneTagItems(tags_orig))
  209.             {
  210.                 if(FilterTagItems(tags,usraccess_tags,TAGFILTER_AND))
  211.                     {
  212.                         struct UserAccess *ua=NULL;
  213.                         struct TagItem *tstate,*tag;
  214.                         APTR data;
  215.                         tstate=tags;
  216.                         {
  217.                             if(tag=FindTagItem(UNTAG_UserAccess,((struct UserNode *) node)->un_Pointers))
  218.                                 {
  219.                                     if(tag->ti_Data)
  220.                                         ua=(struct UserAccess *) tag->ti_Data;
  221.                                 }
  222.                         }
  223.                         if(ua)
  224.                             {
  225.                                 while(tag=NextTagItem(&tstate))
  226.                                     {
  227.                                         data=(APTR) tag->ti_Data;
  228.                                         switch(tag->ti_Tag)
  229.                                             {
  230.                                                 case USRTAG_AccessLevel:
  231.                                                     *((UBYTE *) data)=ua->ua_AccessLevel;
  232.                                                     break;
  233.                                                 case USRTAG_SessionTimeLimit:
  234.                                                     *((UWORD *) data)=ua->ua_SessionTimeLimit;
  235.                                                     break;
  236.                                                 case USRTAG_InactivityTimeLimit:
  237.                                                     *((UWORD *) data)=ua->ua_InactivityTimeLimit;
  238.                                                     break;
  239.                                                 case USRTAG_RatioByte:
  240.                                                     *((UBYTE *) data)=ua->ua_RatioByte;
  241.                                                     break;
  242.                                                 case USRTAG_RatioFile:
  243.                                                     *((UBYTE *) data)=ua->ua_RatioFile;
  244.                                                     break;
  245.                                                 case USRTAG_Days:
  246.                                                     *((ULONG *) data)=ua->ua_Days;
  247.                                                     break;
  248.                                             }
  249.                                         ret++;
  250.                                     }
  251.                             }
  252.                     }
  253.                 FreeTagItems(tags);
  254.             }
  255.         return(ret);
  256.     }
  257.  
  258. ULONG SetUserAccessFields(struct Node *node,struct TagItem *tags_orig)
  259.     {
  260.         ULONG ret=0,retminus=0;
  261.         struct TagItem *tags;
  262.         if(tags=CloneTagItems(tags_orig))
  263.             {
  264.                 if(FilterTagItems(tags,usraccess_tags,TAGFILTER_AND))
  265.                     {
  266.                         struct UserAccess *ua=NULL;
  267.                         struct TagItem *tstate,*tag;
  268.                         APTR data;
  269.                         {
  270.                             if(tag=FindTagItem(UNTAG_UserAccess,((struct UserNode *) node)->un_Pointers))
  271.                                 {
  272.                                     if(tag->ti_Data)
  273.                                         ua=(struct UserAccess *) tag->ti_Data;
  274.                                 }
  275.                         }
  276.                         if(ua)
  277.                             {
  278.                                 tstate=tags;
  279.                                 while(tag=NextTagItem(&tstate))
  280.                                     {
  281.                                         data=(APTR) tag->ti_Data;
  282.                                         switch(tag->ti_Tag)
  283.                                             {
  284.                                                 case USRTAG_AccessLevel:
  285.                                                     ua->ua_AccessLevel=(UBYTE) data;
  286.                                                     break;
  287.                                                 case USRTAG_SessionTimeLimit:
  288.                                                     ua->ua_SessionTimeLimit=(UWORD) data;
  289.                                                     break;
  290.                                                 case USRTAG_InactivityTimeLimit:
  291.                                                     ua->ua_InactivityTimeLimit=(UWORD) data;
  292.                                                     break;
  293.                                                 case USRTAG_RatioByte:
  294.                                                     ua->ua_RatioByte=(UBYTE) data;
  295.                                                     break;
  296.                                                 case USRTAG_RatioFile:
  297.                                                     ua->ua_RatioFile=(UBYTE) data;
  298.                                                     break;
  299.                                                 case USRTAG_Days:
  300.                                                     ua->ua_Days=(ULONG) data;
  301.                                                     break;
  302.                                             }
  303.                                         ret++;
  304.                                     }
  305.                             }
  306.                     }
  307.                 FreeTagItems(tags);
  308.             }
  309.         ret-=retminus;
  310.         return(ret);
  311.     }
  312.  
  313. ULONG GetUserPrefsFields(struct Node *node,struct TagItem *tags_orig)
  314.     {
  315.         ULONG ret=0;
  316.         struct TagItem *tags;
  317.         if(tags=CloneTagItems(tags_orig))
  318.             {
  319.                 if(FilterTagItems(tags,usrprefs_tags,TAGFILTER_AND))
  320.                     {
  321.                         struct UserPrefs *up=NULL;
  322.                         struct TagItem *tstate,*tag;
  323.                         APTR data;
  324.                         {
  325.                             if(tag=FindTagItem(UNTAG_UserPrefs,((struct UserNode *) node)->un_Pointers))
  326.                                 {
  327.                                     if(tag->ti_Data)
  328.                                         up=(struct UserPrefs *) tag->ti_Data;
  329.                                 }
  330.                         }
  331.                         if(up)
  332.                             {
  333.                                 tstate=tags;
  334.                                 while(tag=NextTagItem(&tstate))
  335.                                     {
  336.                                         data=(APTR) tag->ti_Data;
  337.                                         switch(tag->ti_Tag)
  338.                                             {
  339.                                                 case USRTAG_ScreenWidth:
  340.                                                     *((UBYTE *) data)=up->up_ScreenWidth;
  341.                                                     break;
  342.                                                 case USRTAG_ScreenHeight:
  343.                                                     *((UBYTE *) data)=up->up_ScreenHeight;
  344.                                                     break;
  345.                                                 case USRTAG_LogonStack:
  346.                                                     strcpy((STRPTR) data,up->up_LogonStack);
  347.                                                     break;
  348.                                                 case USRTAG_Editor:
  349.                                                     strcpy((STRPTR) data,up->up_Editor);
  350.                                                     break;
  351.                                                 case USRTAG_Protocol:
  352.                                                     strcpy((STRPTR) data,up->up_Protocol);
  353.                                                     break;
  354.                                                 case USRTAG_Archiver:
  355.                                                     strcpy((STRPTR) data,up->up_Archiver);
  356.                                                     break;
  357.                                                 case USRTAG_HotKeys:
  358.                                                     *((BOOL *) data)=(up->up_Flags & UPFLG_HotKeys) ? TRUE : FALSE;
  359.                                                     break;
  360.                                                 case USRTAG_Menus:
  361.                                                     *((BOOL *) data)=(up->up_Flags & UPFLG_NoMenus) ? FALSE : TRUE;
  362.                                                     break;
  363.                                                 case USRTAG_UserMonitor:
  364.                                                     *((BOOL *) data)=(up->up_Flags & UPFLG_NoUserMonitor) ? FALSE : TRUE;
  365.                                                     break;
  366.                                             }
  367.                                         ret++;
  368.                                     }
  369.                             }
  370.                     }
  371.                 FreeTagItems(tags);
  372.             }
  373.         return(ret);
  374.     }
  375.  
  376. ULONG SetUserPrefsFields(struct Node *node,struct TagItem *tags_orig)
  377.     {
  378.         ULONG ret=0,retminus=0;
  379.         struct TagItem *tags;
  380.         if(tags=CloneTagItems(tags_orig))
  381.             {
  382.                 if(FilterTagItems(tags,usrprefs_tags,TAGFILTER_AND))
  383.                     {
  384.                         struct UserPrefs *up=NULL;
  385.                         struct TagItem *tstate,*tag;
  386.                         APTR data;
  387.                         {
  388.                             if(tag=FindTagItem(UNTAG_UserPrefs,((struct UserNode *) node)->un_Pointers))
  389.                                 {
  390.                                     if(tag->ti_Data)
  391.                                         up=(struct UserPrefs *) tag->ti_Data;
  392.                                 }
  393.                         }
  394.                         if(up)
  395.                             {
  396.                                 tstate=tags;
  397.                                 while(tag=NextTagItem(&tstate))
  398.                                     {
  399.                                         data=(APTR) tag->ti_Data;
  400.                                         switch(tag->ti_Tag)
  401.                                             {
  402.                                                 case USRTAG_ScreenWidth:
  403.                                                     up->up_ScreenWidth=(UBYTE) data;
  404.                                                     break;
  405.                                                 case USRTAG_ScreenHeight:
  406.                                                     up->up_ScreenHeight=(UBYTE) data;
  407.                                                     break;
  408.                                                 case USRTAG_LogonStack:
  409.                                                     if(data && strlen((STRPTR) data)<=20)
  410.                                                         strcpy(up->up_LogonStack,(STRPTR) data);
  411.                                                     else
  412.                                                         retminus++;
  413.                                                     break;
  414.                                                 case USRTAG_Editor:
  415.                                                     if(data && strlen((STRPTR) data)<=32)
  416.                                                         strcpy(up->up_Editor,(STRPTR) data);
  417.                                                     else
  418.                                                         retminus++;
  419.                                                     break;
  420.                                                 case USRTAG_Protocol:
  421.                                                     if(data && strlen((STRPTR) data)<=32)
  422.                                                         strcpy(up->up_Protocol,(STRPTR) data);
  423.                                                     else
  424.                                                         retminus++;
  425.                                                     break;
  426.                                                 case USRTAG_Archiver:
  427.                                                     if(data && strlen((STRPTR) data)<=32)
  428.                                                         strcpy(up->up_Archiver,(STRPTR) data);
  429.                                                     else
  430.                                                         retminus++;
  431.                                                     break;
  432.                                                 case USRTAG_HotKeys:
  433.                                                     if((BOOL) data)
  434.                                                         up->up_Flags|=UPFLG_HotKeys;
  435.                                                     else
  436.                                                         up->up_Flags&=~UPFLG_HotKeys;
  437.                                                     break;
  438.                                                 case USRTAG_Menus:
  439.                                                     if((BOOL) data)
  440.                                                         up->up_Flags&=~UPFLG_NoMenus;
  441.                                                     else
  442.                                                         up->up_Flags|=UPFLG_NoMenus;
  443.                                                     break;
  444.                                                 case USRTAG_UserMonitor:
  445.                                                     if((BOOL) data)
  446.                                                         up->up_Flags&=~UPFLG_NoUserMonitor;
  447.                                                     else
  448.                                                         up->up_Flags|=UPFLG_NoUserMonitor;
  449.                                                     break;
  450.                                             }
  451.                                         ret++;
  452.                                     }
  453.                             }
  454.                     }
  455.                 FreeTagItems(tags);
  456.             }
  457.         ret-=retminus;
  458.         return(ret);
  459.     }
  460.  
  461. ULONG GetUserStatsFields(struct Node *node,struct TagItem *tags_orig)
  462.     {
  463.         ULONG ret=0;
  464.         struct TagItem *tags;
  465.         if(tags=CloneTagItems(tags_orig))
  466.             {
  467.                 if(FilterTagItems(tags,usrstats_tags,TAGFILTER_AND))
  468.                     {
  469.                         struct UserStats *us=NULL;
  470.                         struct TagItem *tstate,*tag;
  471.                         APTR data;
  472.                         {
  473.                             if(tag=FindTagItem(UNTAG_UserStats,((struct UserNode *) node)->un_Pointers))
  474.                                 {
  475.                                     if(tag->ti_Data)
  476.                                         us=(struct UserStats *) tag->ti_Data;
  477.                                 }
  478.                         }
  479.                         if(us)
  480.                             {
  481.                                 tstate=tags;
  482.                                 while(tag=NextTagItem(&tstate))
  483.                                     {
  484.                                         data=(APTR) tag->ti_Data;
  485.                                         switch(tag->ti_Tag)
  486.                                             {
  487.                                                 case USRTAG_Sessions:
  488.                                                     *((ULONG *) data)=us->us_Sessions;
  489.                                                     break;
  490.                                                 case USRTAG_EmailRead:
  491.                                                     *((ULONG *) data)=us->us_EmailRead;
  492.                                                     break;
  493.                                                 case USRTAG_EmailWritten:
  494.                                                     *((ULONG *) data)=us->us_EmailWritten;
  495.                                                     break;
  496.                                                 case USRTAG_MessagesRead:
  497.                                                     *((ULONG *) data)=us->us_MessagesRead;
  498.                                                     break;
  499.                                                 case USRTAG_MessagesWritten:
  500.                                                     *((ULONG *) data)=us->us_MessagesWritten;
  501.                                                     break;
  502.                                                 case USRTAG_FilesUploaded:
  503.                                                     *((ULONG *) data)=us->us_FilesUploaded;
  504.                                                     break;
  505.                                                 case USRTAG_FilesDownloaded:
  506.                                                     *((ULONG *) data)=us->us_FilesDownloaded;
  507.                                                     break;
  508.                                                 case USRTAG_FilesCredits:
  509.                                                     *((ULONG *) data)=us->us_FilesCredits;
  510.                                                     break;
  511.                                                 case USRTAG_KilosUploaded:
  512.                                                     *((ULONG *) data)=us->us_KilosUploaded;
  513.                                                     break;
  514.                                                 case USRTAG_KilosDownloaded:
  515.                                                     *((ULONG *) data)=us->us_KilosDownloaded;
  516.                                                     break;
  517.                                                 case USRTAG_KilosCredits:
  518.                                                     *((ULONG *) data)=us->us_KilosCredits;
  519.                                                     break;
  520.                                                 case USRTAG_LastOn:
  521.                                                     *((struct DateStamp *) data)=us->us_LastOn;
  522.                                                     break;
  523.                                                 case USRTAG_TimeUsed:
  524.                                                     *((UWORD *) data)=us->us_TimeUsed;
  525.                                                     break;
  526.                                             }
  527.                                         ret++;
  528.                                     }
  529.                             }
  530.                     }
  531.                 FreeTagItems(tags);
  532.             }
  533.         return(ret);
  534.     }
  535.  
  536. ULONG SetUserStatsFields(struct Node *node,struct TagItem *tags_orig)
  537.     {
  538.         ULONG ret=0,retminus=0;
  539.         struct TagItem *tags;
  540.         if(tags=CloneTagItems(tags_orig))
  541.             {
  542.                 if(FilterTagItems(tags,usrstats_tags,TAGFILTER_AND))
  543.                     {
  544.                         struct UserStats *us=NULL;
  545.                         struct TagItem *tstate,*tag;
  546.                         APTR data;
  547.                         {
  548.                             if(tag=FindTagItem(UNTAG_UserStats,((struct UserNode *) node)->un_Pointers))
  549.                                 {
  550.                                     if(tag->ti_Data)
  551.                                         us=(struct UserStats *) tag->ti_Data;
  552.                                 }
  553.                         }
  554.                         if(us)
  555.                             {
  556.                                 tstate=tags;
  557.                                 while(tag=NextTagItem(&tstate))
  558.                                     {
  559.                                         data=(APTR) tag->ti_Data;
  560.                                         switch(tag->ti_Tag)
  561.                                             {
  562.                                                 case USRTAG_Sessions:
  563.                                                     us->us_Sessions=(ULONG) data;
  564.                                                     break;
  565.                                                 case USRTAG_EmailRead:
  566.                                                     us->us_EmailRead=(ULONG) data;
  567.                                                     break;
  568.                                                 case USRTAG_EmailWritten:
  569.                                                     us->us_EmailWritten=(ULONG) data;
  570.                                                     break;
  571.                                                 case USRTAG_MessagesRead:
  572.                                                     us->us_MessagesRead=(ULONG) data;
  573.                                                     break;
  574.                                                 case USRTAG_MessagesWritten:
  575.                                                     us->us_MessagesWritten=(ULONG) data;
  576.                                                     break;
  577.                                                 case USRTAG_FilesUploaded:
  578.                                                     us->us_FilesUploaded=(ULONG) data;
  579.                                                     break;
  580.                                                 case USRTAG_FilesDownloaded:
  581.                                                     us->us_FilesDownloaded=(ULONG) data;
  582.                                                     break;
  583.                                                 case USRTAG_FilesCredits:
  584.                                                     us->us_FilesCredits=(ULONG) data;
  585.                                                     break;
  586.                                                 case USRTAG_KilosUploaded:
  587.                                                     us->us_KilosUploaded=(ULONG) data;
  588.                                                     break;
  589.                                                 case USRTAG_KilosDownloaded:
  590.                                                     us->us_KilosDownloaded=(ULONG) data;
  591.                                                     break;
  592.                                                 case USRTAG_KilosCredits:
  593.                                                     us->us_KilosCredits=(ULONG) data;
  594.                                                     break;
  595.                                                 case USRTAG_LastOn:
  596.                                                     if(data)
  597.                                                         us->us_LastOn=*((struct DateStamp *) data);
  598.                                                     break;
  599.                                                 case USRTAG_TimeUsed:
  600.                                                     us->us_TimeUsed=(UWORD) data;
  601.                                                     break;
  602.                                             }
  603.                                         ret++;
  604.                                     }
  605.                             }
  606.                     }
  607.                 FreeTagItems(tags);
  608.             }
  609.         ret-=retminus;
  610.         return(ret);
  611.     }
  612.  
  613. struct Node *FindUser(BYTE *name)
  614.     {
  615.         struct Node *ret=NULL;
  616.         if(!stricmp(name,"Sysop"))
  617.             {
  618.                 struct Node *node=NULL;
  619.                 node=UserList.lh_Head;
  620.                 if(node->ln_Succ)
  621.                     ret=node;
  622.             }
  623.         else
  624.             {
  625.                 struct Node *node=NULL;
  626.                 for(node=UserList.lh_Head;node->ln_Succ;node=node->ln_Succ)
  627.                     {
  628.                         ObtainSemaphoreShared(&(((struct UserNode *) node)->un_Semaphore));
  629.                         if(!stricmp(name,((struct UserNode *) node)->un_UserName) || !stricmp(name,((struct UserNode *) node)->un_RealName) || !stricmp(name,((struct UserNode *) node)->un_UUCPName))
  630.                             ret=node;
  631.                         ReleaseSemaphore(&(((struct UserNode *) node)->un_Semaphore));
  632.                         if(ret)
  633.                             break;
  634.                     }
  635.             }
  636.         return(ret);
  637.     }
  638.  
  639. void LoadUserIndex(BYTE *userindexfile)
  640.     {
  641.         BPTR fh;
  642.         ObtainSemaphore(&UserSemaphore);
  643.         if(fh=Open(userindexfile,MODE_OLDFILE))
  644.             {
  645.                 BOOL kg=TRUE;
  646.                 LONG cmd;
  647.                 struct Node *node=NULL;
  648.                 while(kg)
  649.                     {
  650.                         cmd=FGetC(fh);
  651.                         switch(cmd)
  652.                             {
  653.                                 case -1: /* EOF */
  654.                                     kg=FALSE;
  655.                                     break;
  656.                                 case USRCMD_Begin:
  657.                                     if(node=AllocVec(sizeof(struct UserNode),MEMF_CLEAR))
  658.                                         {
  659.                                             InitSemaphore(&(((struct UserNode *) node)->un_Semaphore));
  660.                                             {
  661.                                                 ULONG count=1;
  662.                                                 int i=0;
  663.                                                 while(usernode_tags[i]!=TAG_END)
  664.                                                     {
  665.                                                         count++;
  666.                                                         i++;
  667.                                                     }
  668.                                                 ((struct UserNode *) node)->un_Offsets=AllocateTagItems(count);
  669.                                                 ((struct UserNode *) node)->un_Pointers=AllocateTagItems(count);
  670.                                                 if(((struct UserNode *) node)->un_Offsets && ((struct UserNode *) node)->un_Pointers)
  671.                                                     {
  672.                                                         for(i=0;i<count;i++)
  673.                                                             {
  674.                                                                 ((struct UserNode *) node)->un_Offsets[i].ti_Tag=usernode_tags[i];
  675.                                                                 ((struct UserNode *) node)->un_Offsets[i].ti_Data=(usernode_tags[i]==TAG_END) ? (ULONG) 0 : (ULONG) ~0;
  676.                                                                 ((struct UserNode *) node)->un_Pointers[i].ti_Tag=usernode_tags[i];
  677.                                                                 ((struct UserNode *) node)->un_Pointers[i].ti_Data=(ULONG) 0;
  678.                                                             }
  679.                                                     }
  680.                                                 else
  681.                                                     {
  682.                                                         if(((struct UserNode *) node)->un_Offsets) FreeTagItems(((struct UserNode *) node)->un_Offsets);
  683.                                                         if(((struct UserNode *) node)->un_Pointers) FreeTagItems(((struct UserNode *) node)->un_Pointers);
  684.                                                         FreeVec(node);
  685.                                                         kg=FALSE;
  686.                                                     }
  687.                                             }
  688.                                         }
  689.                                     else
  690.                                         kg=FALSE;
  691.                                     break;
  692.                                 case USRCMD_End:
  693.                                     if(node)
  694.                                         {
  695.                                             AddTail(&UserList,node);
  696.                                             node=NULL;
  697.                                         }
  698.                                     break;
  699.                                 case USRCMD_Field:
  700.                                     if(node)
  701.                                         {
  702.                                             LONG field;
  703.                                             UWORD size;
  704.                                             if( ((field=FGetC(fh))!=-1) && (FRead(fh,&size,sizeof(UWORD),1)) )
  705.                                                 {
  706.                                                     APTR data;
  707.                                                     if(data=AllocVec(size,MEMF_CLEAR))
  708.                                                         {
  709.                                                             if(FRead(fh,data,size,1))
  710.                                                                 {
  711.                                                                     switch(field)
  712.                                                                         {
  713.                                                                             case USRFLD_UserName:
  714.                                                                                 strcpy(((struct UserNode *) node)->un_UserName,(STRPTR) data);
  715.                                                                                 break;
  716.                                                                             case USRFLD_RealName:
  717.                                                                                 strcpy(((struct UserNode *) node)->un_RealName,(STRPTR) data);
  718.                                                                                 break;
  719.                                                                             case USRFLD_UUCPName:
  720.                                                                                 strcpy(((struct UserNode *) node)->un_UUCPName,(STRPTR) data);
  721.                                                                                 break;
  722.                                                                             case USRFLD_Offset:
  723.                                                                                 {
  724.                                                                                     struct TagItem *tag;
  725.                                                                                     if(tag=FindTagItem(((struct OffsetStruct *) data)->os_Type,((struct UserNode *) node)->un_Offsets))
  726.                                                                                         tag->ti_Data=((struct OffsetStruct *) data)->os_Offset;
  727.                                                                                 }
  728.                                                                                 break;
  729.                                                                         }
  730.                                                                 }
  731.                                                             else
  732.                                                                 kg=FALSE;
  733.                                                             FreeVec(data);
  734.                                                         }
  735.                                                     else
  736.                                                         kg=FALSE;
  737.                                                 }
  738.                                             else
  739.                                                 kg=FALSE;
  740.                                         }
  741.                                     break;
  742.                             }
  743.                     }
  744.                 Close(fh);
  745.             }
  746.         ReleaseSemaphore(&UserSemaphore);
  747.     }
  748.  
  749. void SaveUserIndex(BYTE *userindexfile)
  750.     {
  751.         BPTR fh;
  752.         ObtainSemaphore(&UserSemaphore);
  753.         if(fh=Open(userindexfile,MODE_NEWFILE))
  754.             {
  755.                 {
  756.                     struct Node *node;
  757.                     for(node=UserList.lh_Head;node->ln_Succ;node=node->ln_Succ)
  758.                         {
  759.                             FPutC(fh,USRCMD_Begin);
  760.                             SaveUserField(fh,USRFLD_UserName,strlen(((struct UserNode *) node)->un_UserName)+1,((struct UserNode *) node)->un_UserName);
  761.                             SaveUserField(fh,USRFLD_RealName,strlen(((struct UserNode *) node)->un_RealName)+1,((struct UserNode *) node)->un_RealName);
  762.                             SaveUserField(fh,USRFLD_UUCPName,strlen(((struct UserNode *) node)->un_UUCPName)+1,((struct UserNode *) node)->un_UUCPName);
  763.                             {
  764.                                 struct OffsetStruct os;
  765.                                 struct TagItem *tstate,*tag;
  766.                                 tstate=((struct UserNode *) node)->un_Offsets;
  767.                                 while(tag=NextTagItem(&tstate))
  768.                                     {
  769.                                         if(tag->ti_Data!=(ULONG) ~0)
  770.                                             {
  771.                                                 os.os_Type=tag->ti_Tag;
  772.                                                 os.os_Offset=tag->ti_Data;
  773.                                                 SaveUserField(fh,USRFLD_Offset,sizeof(struct OffsetStruct),&os);
  774.                                             }
  775.                                     }
  776.                             }
  777.                             FPutC(fh,USRCMD_End);
  778.                         }
  779.                 }
  780.                 Close(fh);
  781.             }
  782.         ReleaseSemaphore(&UserSemaphore);
  783.     }
  784.  
  785. void UnLoadUserIndex()
  786.     {
  787.         ObtainSemaphore(&UserSemaphore);
  788.         {
  789.             struct Node *node;
  790.             while(node=RemHead(&UserList))
  791.                 {
  792.                     FreeTagItems(((struct UserNode *) node)->un_Offsets);
  793.                     {
  794.                         struct TagItem *tstate,*tag;
  795.                         tstate=((struct UserNode *) node)->un_Pointers;
  796.                         while(tag=NextTagItem(&tstate))
  797.                             {
  798.                                 if(tag->ti_Data)
  799.                                     FreeVec((APTR) tag->ti_Data);
  800.                             }
  801.                     }
  802.                     FreeTagItems(((struct UserNode *) node)->un_Pointers);
  803.                     FreeVec(node);
  804.                 }
  805.         }
  806.         ReleaseSemaphore(&UserSemaphore);
  807.     }
  808.  
  809. BOOL LoadUserData(BYTE *userdatafile,struct Node *node,ULONG usertag)
  810.     {
  811.         BOOL ret=FALSE;
  812.         ULONG pos;
  813.         if(!GetTagData(usertag,0,((struct UserNode *) node)->un_Pointers))
  814.             {
  815.                 if( (pos=GetTagData(usertag,(ULONG) ~0,((struct UserNode *) node)->un_Offsets)) != (ULONG) ~0 )
  816.                     {
  817.                         BPTR fh;
  818.                         if(fh=Open(userdatafile,MODE_OLDFILE))
  819.                             {
  820.                                 Seek(fh,pos,OFFSET_BEGINNING);
  821.                                 {
  822.                                     BOOL kg=TRUE;
  823.                                     LONG cmd;
  824.                                     APTR data=NULL;
  825.                                     while(kg)
  826.                                         {
  827.                                             cmd=FGetC(fh);
  828.                                             switch(cmd)
  829.                                                 {
  830.                                                     case -1: /* EOF */
  831.                                                         kg=FALSE;
  832.                                                         break;
  833.                                                     case USRCMD_Begin:
  834.                                                         {
  835.                                                             ULONG size=0;
  836.                                                             switch(usertag)
  837.                                                                 {
  838.                                                                     case UNTAG_UserInfo:
  839.                                                                         size=sizeof(struct UserInfo);
  840.                                                                         break;
  841.                                                                     case UNTAG_UserAccess:
  842.                                                                         size=sizeof(struct UserAccess);
  843.                                                                         break;
  844.                                                                     case UNTAG_UserPrefs:
  845.                                                                         size=sizeof(struct UserPrefs);
  846.                                                                         break;
  847.                                                                     case UNTAG_UserStats:
  848.                                                                         size=sizeof(struct UserStats);
  849.                                                                         break;
  850.                                                                 }
  851.                                                             if(size)
  852.                                                                 {
  853.                                                                     if(data=AllocVec(size,MEMF_CLEAR))
  854.                                                                         {
  855.                                                                             struct TagItem *tag;
  856.                                                                             if(tag=FindTagItem(usertag,((struct UserNode *) node)->un_Pointers))
  857.                                                                                 tag->ti_Data=(ULONG) data;
  858.                                                                         }
  859.                                                                     else
  860.                                                                         kg=FALSE;
  861.                                                                 }
  862.                                                             else
  863.                                                                 kg=FALSE;
  864.                                                         }
  865.                                                         break;
  866.                                                     case USRCMD_End:
  867.                                                         ret=TRUE;
  868.                                                         kg=FALSE;
  869.                                                         break;
  870.                                                     case USRCMD_Field:
  871.                                                         if(data)
  872.                                                             {
  873.                                                                 LONG field;
  874.                                                                 UWORD size;
  875.                                                                 if( ((field=FGetC(fh))!=-1) && (FRead(fh,&size,sizeof(UWORD),1)) )
  876.                                                                     {
  877.                                                                         APTR fielddata;
  878.                                                                         if(fielddata=AllocVec(size,MEMF_CLEAR))
  879.                                                                             {
  880.                                                                                 if(FRead(fh,fielddata,size,1))
  881.                                                                                     {
  882.                                                                                         switch(usertag)
  883.                                                                                             {
  884.                                                                                                 case UNTAG_UserInfo:
  885.                                                                                                     switch(field)
  886.                                                                                                         {
  887.                                                                                                             case USRFLD_Password:
  888.                                                                                                                 strcpy(((struct UserInfo *) data)->ui_Password,(STRPTR) fielddata);
  889.                                                                                                                 break;
  890.                                                                                                             case USRFLD_Address:
  891.                                                                                                                 strcpy(((struct UserInfo *) data)->ui_Address,(STRPTR) fielddata);
  892.                                                                                                                 break;
  893.                                                                                                             case USRFLD_City:
  894.                                                                                                                 strcpy(((struct UserInfo *) data)->ui_City,(STRPTR) fielddata);
  895.                                                                                                                 break;
  896.                                                                                                             case USRFLD_State:
  897.                                                                                                                 strcpy(((struct UserInfo *) data)->ui_State,(STRPTR) fielddata);
  898.                                                                                                                 break;
  899.                                                                                                             case USRFLD_Zip:
  900.                                                                                                                 strcpy(((struct UserInfo *) data)->ui_Zip,(STRPTR) fielddata);
  901.                                                                                                                 break;
  902.                                                                                                             case USRFLD_Country:
  903.                                                                                                                 strcpy(((struct UserInfo *) data)->ui_Country,(STRPTR) fielddata);
  904.                                                                                                                 break;
  905.                                                                                                             case USRFLD_PhoneCode:
  906.                                                                                                                 strcpy(((struct UserInfo *) data)->ui_PhoneCode,(STRPTR) fielddata);
  907.                                                                                                                 break;
  908.                                                                                                             case USRFLD_PhoneNumber:
  909.                                                                                                                 strcpy(((struct UserInfo *) data)->ui_PhoneNumber,(STRPTR) fielddata);
  910.                                                                                                                 break;
  911.                                                                                                             case USRFLD_BirthDay:
  912.                                                                                                                 ((struct UserInfo *) data)->ui_BirthDay=*((UBYTE *) fielddata);
  913.                                                                                                                 break;
  914.                                                                                                             case USRFLD_BirthMonth:
  915.                                                                                                                 ((struct UserInfo *) data)->ui_BirthMonth=*((UBYTE *) fielddata);
  916.                                                                                                                 break;
  917.                                                                                                             case USRFLD_BirthYear:
  918.                                                                                                                 ((struct UserInfo *) data)->ui_BirthYear=*((UWORD *) fielddata);
  919.                                                                                                                 break;
  920.                                                                                                         }
  921.                                                                                                     break;
  922.                                                                                                 case UNTAG_UserAccess:
  923.                                                                                                     switch(field)
  924.                                                                                                         {
  925.                                                                                                             case USRFLD_AccessLevel:
  926.                                                                                                                 ((struct UserAccess *) data)->ua_AccessLevel=*((UBYTE *) fielddata);
  927.                                                                                                                 break;
  928.                                                                                                             case USRFLD_SessionTimeLimit:
  929.                                                                                                                 ((struct UserAccess *) data)->ua_SessionTimeLimit=*((UWORD *) fielddata);
  930.                                                                                                                 break;
  931.                                                                                                             case USRFLD_InactivityTimeLimit:
  932.                                                                                                                 ((struct UserAccess *) data)->ua_InactivityTimeLimit=*((UWORD *) fielddata);
  933.                                                                                                                 break;
  934.                                                                                                             case USRFLD_RatioByte:
  935.                                                                                                                 ((struct UserAccess *) data)->ua_RatioByte=*((UBYTE *) fielddata);
  936.                                                                                                                 break;
  937.                                                                                                             case USRFLD_RatioFile:
  938.                                                                                                                 ((struct UserAccess *) data)->ua_RatioFile=*((UBYTE *) fielddata);
  939.                                                                                                                 break;
  940.                                                                                                             case USRFLD_Days:
  941.                                                                                                                 ((struct UserAccess *) data)->ua_Days=*((ULONG *) fielddata);
  942.                                                                                                                 break;
  943.                                                                                                         }
  944.                                                                                                     break;
  945.                                                                                                 case UNTAG_UserPrefs:
  946.                                                                                                     switch(field)
  947.                                                                                                         {
  948.                                                                                                             case USRFLD_ScreenWidth:
  949.                                                                                                                 ((struct UserPrefs *) data)->up_ScreenWidth=*((UBYTE *) fielddata);
  950.                                                                                                                 break;
  951.                                                                                                             case USRFLD_ScreenHeight:
  952.                                                                                                                 ((struct UserPrefs *) data)->up_ScreenHeight=*((UBYTE *) fielddata);
  953.                                                                                                                 break;
  954.                                                                                                             case USRFLD_LogonStack:
  955.                                                                                                                 strcpy(((struct UserPrefs *) data)->up_LogonStack,(STRPTR) fielddata);
  956.                                                                                                                 break;
  957.                                                                                                             case USRFLD_Editor:
  958.                                                                                                                 strcpy(((struct UserPrefs *) data)->up_Editor,(STRPTR) fielddata);
  959.                                                                                                                 break;
  960.                                                                                                             case USRFLD_Protocol:
  961.                                                                                                                 strcpy(((struct UserPrefs *) data)->up_Protocol,(STRPTR) fielddata);
  962.                                                                                                                 break;
  963.                                                                                                             case USRFLD_Archiver:
  964.                                                                                                                 strcpy(((struct UserPrefs *) data)->up_Archiver,(STRPTR) fielddata);
  965.                                                                                                                 break;
  966.                                                                                                             case USRFLD_Flags:
  967.                                                                                                                 ((struct UserPrefs *) data)->up_Flags=*((ULONG *) fielddata);
  968.                                                                                                                 break;
  969.                                                                                                         }
  970.                                                                                                     break;
  971.                                                                                                 case UNTAG_UserStats:
  972.                                                                                                     switch(field)
  973.                                                                                                         {
  974.                                                                                                             case USRFLD_Sessions:
  975.                                                                                                                 ((struct UserStats *) data)->us_Sessions=*((ULONG *) fielddata);
  976.                                                                                                                 break;
  977.                                                                                                             case USRFLD_EmailRead:
  978.                                                                                                                 ((struct UserStats *) data)->us_EmailRead=*((ULONG *) fielddata);
  979.                                                                                                                 break;
  980.                                                                                                             case USRFLD_EmailWritten:
  981.                                                                                                                 ((struct UserStats *) data)->us_EmailWritten=*((ULONG *) fielddata);
  982.                                                                                                                 break;
  983.                                                                                                             case USRFLD_MessagesRead:
  984.                                                                                                                 ((struct UserStats *) data)->us_MessagesRead=*((ULONG *) fielddata);
  985.                                                                                                                 break;
  986.                                                                                                             case USRFLD_MessagesWritten:
  987.                                                                                                                 ((struct UserStats *) data)->us_MessagesWritten=*((ULONG *) fielddata);
  988.                                                                                                                 break;
  989.                                                                                                             case USRFLD_FilesUploaded:
  990.                                                                                                                 ((struct UserStats *) data)->us_FilesUploaded=*((ULONG *) fielddata);
  991.                                                                                                                 break;
  992.                                                                                                             case USRFLD_FilesDownloaded:
  993.                                                                                                                 ((struct UserStats *) data)->us_FilesDownloaded=*((ULONG *) fielddata);
  994.                                                                                                                 break;
  995.                                                                                                             case USRFLD_FilesCredits:
  996.                                                                                                                 ((struct UserStats *) data)->us_FilesCredits=*((ULONG *) fielddata);
  997.                                                                                                                 break;
  998.                                                                                                             case USRFLD_KilosUploaded:
  999.                                                                                                                 ((struct UserStats *) data)->us_KilosUploaded=*((ULONG *) fielddata);
  1000.                                                                                                                 break;
  1001.                                                                                                             case USRFLD_KilosDownloaded:
  1002.                                                                                                                 ((struct UserStats *) data)->us_KilosDownloaded=*((ULONG *) fielddata);
  1003.                                                                                                                 break;
  1004.                                                                                                             case USRFLD_KilosCredits:
  1005.                                                                                                                 ((struct UserStats *) data)->us_KilosCredits=*((ULONG *) fielddata);
  1006.                                                                                                                 break;
  1007.                                                                                                             case USRFLD_LastOn:
  1008.                                                                                                                 ((struct UserStats *) data)->us_LastOn=*((struct DateStamp *) fielddata);
  1009.                                                                                                                 break;
  1010.                                                                                                             case USRFLD_TimeUsed:
  1011.                                                                                                                 ((struct UserStats *) data)->us_TimeUsed=*((UWORD *) fielddata);
  1012.                                                                                                                 break;
  1013.                                                                                                         }
  1014.                                                                                                     break;
  1015.                                                                                             }
  1016.                                                                                     }
  1017.                                                                                 else
  1018.                                                                                     kg=FALSE;
  1019.                                                                                 FreeVec(fielddata);
  1020.                                                                             }
  1021.                                                                         else
  1022.                                                                             kg=FALSE;
  1023.                                                                     }
  1024.                                                                 else
  1025.                                                                     kg=FALSE;
  1026.                                                             }
  1027.                                                         break;
  1028.                                                 }
  1029.                                         }
  1030.                                 }
  1031.                                 Close(fh);
  1032.                             }
  1033.                     }
  1034.                 else
  1035.                     {
  1036.                         ULONG size=0;
  1037.                         switch(usertag)
  1038.                             {
  1039.                                 case UNTAG_UserInfo:
  1040.                                     size=sizeof(struct UserInfo);
  1041.                                     break;
  1042.                                 case UNTAG_UserAccess:
  1043.                                     size=sizeof(struct UserAccess);
  1044.                                     break;
  1045.                                 case UNTAG_UserPrefs:
  1046.                                     size=sizeof(struct UserPrefs);
  1047.                                     break;
  1048.                                 case UNTAG_UserStats:
  1049.                                     size=sizeof(struct UserStats);
  1050.                                     break;
  1051.                             }
  1052.                         if(size)
  1053.                             {
  1054.                                 APTR data;
  1055.                                 if(data=AllocVec(size,MEMF_CLEAR))
  1056.                                     {
  1057.                                         struct TagItem *tag;
  1058.                                         if(tag=FindTagItem(usertag,((struct UserNode *) node)->un_Pointers))
  1059.                                             {
  1060.                                                 tag->ti_Data=(ULONG) data;
  1061.                                                 ret=TRUE;
  1062.                                             }
  1063.                                     }
  1064.                             }
  1065.                     }
  1066.             }
  1067.         return(ret);
  1068.     }
  1069.  
  1070. void SaveUserData(BYTE *userdatafile,ULONG usertag)
  1071.     {
  1072.         BPTR fh_in,fh_out;
  1073.         BYTE infile[64];
  1074.         sprintf(infile,"%s.bak",userdatafile);
  1075.         ObtainSemaphore(&UserSemaphore);
  1076.         Rename(userdatafile,infile);
  1077.         fh_in=Open(infile,MODE_OLDFILE);
  1078.         fh_out=Open(userdatafile,MODE_NEWFILE);
  1079.         if(fh_out)
  1080.             {
  1081.                 struct UserNode *node;
  1082.                 ULONG offset,pointer,outfilepos=0;
  1083.                 for(node=(struct UserNode *) UserList.lh_Head;node->un_Node.ln_Succ;node=(struct UserNode *) node->un_Node.ln_Succ)
  1084.                     {
  1085.                         {
  1086.                             offset=GetTagData(usertag,(ULONG) ~0,node->un_Offsets);
  1087.                             pointer=GetTagData(usertag,0,node->un_Pointers);
  1088.                         }
  1089.                         if(pointer)
  1090.                             {
  1091.                                 {
  1092.                                     struct TagItem *tag;
  1093.                                     if(tag=FindTagItem(usertag,node->un_Offsets))
  1094.                                         tag->ti_Data=outfilepos;
  1095.                                 }
  1096.                                 FPutC(fh_out,USRCMD_Begin);outfilepos++;
  1097.                                 switch(usertag)
  1098.                                     {
  1099.                                         case UNTAG_UserInfo:
  1100.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Password,strlen(((struct UserInfo *) pointer)->ui_Password)+1,((struct UserInfo *) pointer)->ui_Password);
  1101.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Address,strlen(((struct UserInfo *) pointer)->ui_Address)+1,((struct UserInfo *) pointer)->ui_Address);
  1102.                                             outfilepos+=SaveUserField(fh_out,USRFLD_City,strlen(((struct UserInfo *) pointer)->ui_City)+1,((struct UserInfo *) pointer)->ui_City);
  1103.                                             outfilepos+=SaveUserField(fh_out,USRFLD_State,strlen(((struct UserInfo *) pointer)->ui_State)+1,((struct UserInfo *) pointer)->ui_State);
  1104.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Zip,strlen(((struct UserInfo *) pointer)->ui_Zip)+1,((struct UserInfo *) pointer)->ui_Zip);
  1105.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Country,strlen(((struct UserInfo *) pointer)->ui_Country)+1,((struct UserInfo *) pointer)->ui_Country);
  1106.                                             outfilepos+=SaveUserField(fh_out,USRFLD_PhoneCode,strlen(((struct UserInfo *) pointer)->ui_PhoneCode)+1,((struct UserInfo *) pointer)->ui_PhoneCode);
  1107.                                             outfilepos+=SaveUserField(fh_out,USRFLD_PhoneNumber,strlen(((struct UserInfo *) pointer)->ui_PhoneNumber)+1,((struct UserInfo *) pointer)->ui_PhoneNumber);
  1108.                                             outfilepos+=SaveUserField(fh_out,USRFLD_BirthDay,sizeof(UBYTE),&(((struct UserInfo *) pointer)->ui_BirthDay));
  1109.                                             outfilepos+=SaveUserField(fh_out,USRFLD_BirthMonth,sizeof(UBYTE),&(((struct UserInfo *) pointer)->ui_BirthMonth));
  1110.                                             outfilepos+=SaveUserField(fh_out,USRFLD_BirthYear,sizeof(UWORD),&(((struct UserInfo *) pointer)->ui_BirthYear));
  1111.                                             break;
  1112.                                         case UNTAG_UserAccess:
  1113.                                             outfilepos+=SaveUserField(fh_out,USRFLD_AccessLevel,sizeof(UBYTE),&(((struct UserAccess *) pointer)->ua_AccessLevel));
  1114.                                             outfilepos+=SaveUserField(fh_out,USRFLD_SessionTimeLimit,sizeof(UWORD),&(((struct UserAccess *) pointer)->ua_SessionTimeLimit));
  1115.                                             outfilepos+=SaveUserField(fh_out,USRFLD_InactivityTimeLimit,sizeof(UWORD),&(((struct UserAccess *) pointer)->ua_InactivityTimeLimit));
  1116.                                             outfilepos+=SaveUserField(fh_out,USRFLD_RatioByte,sizeof(UBYTE),&(((struct UserAccess *) pointer)->ua_RatioByte));
  1117.                                             outfilepos+=SaveUserField(fh_out,USRFLD_RatioFile,sizeof(UBYTE),&(((struct UserAccess *) pointer)->ua_RatioFile));
  1118.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Days,sizeof(ULONG),&(((struct UserAccess *) pointer)->ua_Days));
  1119.                                             break;
  1120.                                         case UNTAG_UserPrefs:
  1121.                                             outfilepos+=SaveUserField(fh_out,USRFLD_ScreenWidth,sizeof(UBYTE),&(((struct UserPrefs *) pointer)->up_ScreenWidth));
  1122.                                             outfilepos+=SaveUserField(fh_out,USRFLD_ScreenHeight,sizeof(UBYTE),&(((struct UserPrefs *) pointer)->up_ScreenHeight));
  1123.                                             outfilepos+=SaveUserField(fh_out,USRFLD_LogonStack,strlen(((struct UserPrefs *) pointer)->up_LogonStack)+1,((struct UserPrefs *) pointer)->up_LogonStack);
  1124.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Editor,strlen(((struct UserPrefs *) pointer)->up_Editor)+1,((struct UserPrefs *) pointer)->up_Editor);
  1125.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Protocol,strlen(((struct UserPrefs *) pointer)->up_Protocol)+1,((struct UserPrefs *) pointer)->up_Protocol);
  1126.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Archiver,strlen(((struct UserPrefs *) pointer)->up_Archiver)+1,((struct UserPrefs *) pointer)->up_Archiver);
  1127.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Flags,sizeof(ULONG),&(((struct UserPrefs *) pointer)->up_Flags));
  1128.                                             break;
  1129.                                         case UNTAG_UserStats:
  1130.                                             outfilepos+=SaveUserField(fh_out,USRFLD_Sessions,sizeof(ULONG),&(((struct UserStats *) pointer)->us_Sessions));
  1131.                                             outfilepos+=SaveUserField(fh_out,USRFLD_EmailRead,sizeof(ULONG),&(((struct UserStats *) pointer)->us_EmailRead));
  1132.                                             outfilepos+=SaveUserField(fh_out,USRFLD_EmailWritten,sizeof(ULONG),&(((struct UserStats *) pointer)->us_EmailWritten));
  1133.                                             outfilepos+=SaveUserField(fh_out,USRFLD_MessagesRead,sizeof(ULONG),&(((struct UserStats *) pointer)->us_MessagesRead));
  1134.                                             outfilepos+=SaveUserField(fh_out,USRFLD_MessagesWritten,sizeof(ULONG),&(((struct UserStats *) pointer)->us_MessagesWritten));
  1135.                                             outfilepos+=SaveUserField(fh_out,USRFLD_FilesUploaded,sizeof(ULONG),&(((struct UserStats *) pointer)->us_FilesUploaded));
  1136.                                             outfilepos+=SaveUserField(fh_out,USRFLD_FilesDownloaded,sizeof(ULONG),&(((struct UserStats *) pointer)->us_FilesDownloaded));
  1137.                                             outfilepos+=SaveUserField(fh_out,USRFLD_FilesCredits,sizeof(ULONG),&(((struct UserStats *) pointer)->us_FilesCredits));
  1138.                                             outfilepos+=SaveUserField(fh_out,USRFLD_KilosUploaded,sizeof(ULONG),&(((struct UserStats *) pointer)->us_KilosUploaded));
  1139.                                             outfilepos+=SaveUserField(fh_out,USRFLD_KilosDownloaded,sizeof(ULONG),&(((struct UserStats *) pointer)->us_KilosDownloaded));
  1140.                                             outfilepos+=SaveUserField(fh_out,USRFLD_KilosCredits,sizeof(ULONG),&(((struct UserStats *) pointer)->us_KilosCredits));
  1141.                                             outfilepos+=SaveUserField(fh_out,USRFLD_LastOn,sizeof(struct DateStamp),&(((struct UserStats *) pointer)->us_LastOn));
  1142.                                             outfilepos+=SaveUserField(fh_out,USRFLD_TimeUsed,sizeof(UWORD),&(((struct UserStats *) pointer)->us_TimeUsed));
  1143.                                             break;
  1144.                                     }
  1145.                                 FPutC(fh_out,USRCMD_End);outfilepos++;
  1146.                             }
  1147.                         else
  1148.                             {
  1149.                                 if(offset!=~0 && fh_in)
  1150.                                     {
  1151.                                         {
  1152.                                             struct TagItem *tag;
  1153.                                             if(tag=FindTagItem(usertag,node->un_Offsets))
  1154.                                                 tag->ti_Data=outfilepos;
  1155.                                         }
  1156.                                         Seek(fh_in,offset,OFFSET_BEGINNING);
  1157.                                         {
  1158.                                             BOOL kg=TRUE;
  1159.                                             LONG cmd;
  1160.                                             while(kg)
  1161.                                                 {
  1162.                                                     cmd=FGetC(fh_in);
  1163.                                                     switch(cmd)
  1164.                                                         {
  1165.                                                             case -1: /* EOF */
  1166.                                                                 kg=FALSE;
  1167.                                                                 break;
  1168.                                                             case USRCMD_Begin:
  1169.                                                                 FPutC(fh_out,cmd);outfilepos++;
  1170.                                                                 break;
  1171.                                                             case USRCMD_End:
  1172.                                                                 FPutC(fh_out,cmd);outfilepos++;
  1173.                                                                 kg=FALSE;
  1174.                                                                 break;
  1175.                                                             case USRCMD_Field:
  1176.                                                                 {
  1177.                                                                     LONG field;
  1178.                                                                     UWORD size;
  1179.                                                                     if( ((field=FGetC(fh_in))!=-1) && (FRead(fh_in,&size,sizeof(UWORD),1)) )
  1180.                                                                         {
  1181.                                                                             APTR fielddata;
  1182.                                                                             if(fielddata=AllocVec(size,MEMF_CLEAR))
  1183.                                                                                 {
  1184.                                                                                     if(FRead(fh_in,fielddata,size,1))
  1185.                                                                                         outfilepos+=SaveUserField(fh_out,field,size,fielddata);
  1186.                                                                                     else
  1187.                                                                                         kg=FALSE;
  1188.                                                                                     FreeVec(fielddata);
  1189.                                                                                 }
  1190.                                                                             else
  1191.                                                                                 kg=FALSE;
  1192.                                                                         }
  1193.                                                                     else
  1194.                                                                         kg=FALSE;
  1195.                                                                 }
  1196.                                                                 break;
  1197.                                                         }
  1198.                                                 }
  1199.                                         }
  1200.                                     }
  1201.                             }
  1202.                     }
  1203.                 if(fh_in) Close(fh_in);
  1204.                 Close(fh_out);
  1205.                 DeleteFile(infile);
  1206.             }
  1207.         else
  1208.             {
  1209.                 if(fh_in) Close(fh_in);
  1210.                 if(fh_out) Close(fh_out);
  1211.             }
  1212.         ReleaseSemaphore(&UserSemaphore);
  1213.     }
  1214.  
  1215. void UnLoadUserData(struct Node *node,ULONG usertag)
  1216.     {
  1217.         struct TagItem *tag;
  1218.         if(tag=FindTagItem(usertag,((struct UserNode *) node)->un_Pointers))
  1219.             {
  1220.                 if(tag->ti_Data)
  1221.                     {
  1222.                         FreeVec((APTR) tag->ti_Data);
  1223.                         tag->ti_Data=0;
  1224.                     }
  1225.             }
  1226.     }
  1227.  
  1228. ULONG SaveUserField(BPTR fh,LONG field,UWORD size,APTR data)
  1229.     {
  1230.         ULONG ret=0;
  1231.         FPutC(fh,USRCMD_Field);ret++;
  1232.         FPutC(fh,field);ret++;
  1233.         FWrite(fh,&size,sizeof(UWORD),1);ret+=sizeof(UWORD);
  1234.         FWrite(fh,data,(ULONG) size,1);ret+=size;
  1235.         return(ret);
  1236.     }
  1237.  
  1238. BOOL IsTag(Tag *attrs,struct TagItem *tags_orig)
  1239.     {
  1240.         BOOL ret=FALSE;
  1241.         struct TagItem *tags;
  1242.         if(tags=CloneTagItems(tags_orig))
  1243.             {
  1244.                 if(FilterTagItems(tags,attrs,TAGFILTER_AND))
  1245.                     {
  1246.                         struct TagItem *tstate,*tag;
  1247.                         tstate=tags;
  1248.                         while(tag=NextTagItem(&tstate))
  1249.                             {
  1250.                                 ret=TRUE;
  1251.                             }
  1252.                     }
  1253.                 FreeTagItems(tags);
  1254.             }
  1255.         return(ret);
  1256.     }
  1257.  
  1258. #include <intuition/intuition.h>
  1259. #include <proto/intuition.h>
  1260.  
  1261. void checkpoint(BYTE *s)
  1262.     {
  1263.         struct IntuitionBase *IntuitionBase;
  1264.         if(IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0))
  1265.             {
  1266.                 struct EasyStruct es={ sizeof(struct EasyStruct),NULL,"wwbbs.library checkpoint","%s","Okay" };
  1267.                 EasyRequest(NULL,&es,NULL,s);
  1268.                 CloseLibrary((struct Library *) IntuitionBase);
  1269.             }
  1270.     }
  1271.